from __future__ import annotations

import json
from pathlib import Path
from typing import Dict, List, Tuple

_MAPPING_FILE = Path(__file__).resolve().parent.parent / 'data' / 'connector_credentials_keys.v2.json'

try:
    with _MAPPING_FILE.open('r', encoding='utf-8') as f:
        _CONNECTOR_KEYS: Dict[str, List[str]] = json.load(f)
except FileNotFoundError:
    _CONNECTOR_KEYS = {}

_SUFFIX_PRIORITY: Tuple[str, ...] = ('_perpetual', '_swap', '_futures', '_spot')


def _group_variants() -> Dict[str, Dict[str, Tuple[str, List[str]]]]:
    grouped: Dict[str, Dict[str, Tuple[str, List[str]]]] = {}
    for name, keys in _CONNECTOR_KEYS.items():
        lower = name.lower()
        base = lower
        label = 'spot'
        for suf in _SUFFIX_PRIORITY:
            if lower.endswith(suf):
                base = lower[:-len(suf)]
                label = suf.lstrip('_') or 'spot'
                break
        grouped.setdefault(base, {})[label] = (lower, keys)
    return grouped

_VARIANTS = _group_variants()


def build_connector_payloads(
    connector_name: str,
    credentials: Dict[str, str],
) -> Tuple[Dict[str, Dict[str, str]], Dict[str, List[str]]]:
    connector_lower = connector_name.lower()

    required_keys = _CONNECTOR_KEYS.get(connector_lower)
    if required_keys is None:
        return {connector_lower: credentials}, {}

    base = connector_lower
    for suf in _SUFFIX_PRIORITY:
        if connector_lower.endswith(suf):
            base = connector_lower[:-len(suf)]
            break

    variants = _VARIANTS.get(base, {})
    targets = {connector_lower}
    for info in variants.values():
        targets.add(info[0])

    payloads: Dict[str, Dict[str, str]] = {}
    missing: Dict[str, List[str]] = {}

    for name in targets:
        required = _CONNECTOR_KEYS.get(name)
        if required is None:
            payloads[name] = credentials
            continue
        current_missing = [key for key in required if key not in credentials]
        if current_missing:
            missing[name] = current_missing
            continue
        payloads[name] = {key: credentials[key] for key in required}

    if connector_lower in missing:
        raise KeyError(missing[connector_lower][0])

    for name in list(payloads.keys()):
        if name in missing:
            payloads.pop(name, None)

    return payloads, missing
